package com.netdisk.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.netdisk.dto.LoginDTO;
import com.netdisk.dto.RegisterDTO;
import com.netdisk.dto.StorageStatsDTO;
import com.netdisk.dto.UserDTO;
import com.netdisk.entity.User;
import com.netdisk.exception.BusinessException;
import com.netdisk.mapper.FileMapper;
import com.netdisk.mapper.UserMapper;
import com.netdisk.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户服务实现类
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private FileMapper fileMapper;

    /**
     * 默认存储配额（1GB）
     */
    private static final long DEFAULT_STORAGE_QUOTA = 1024 * 1024 * 1024;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDTO register(RegisterDTO registerDTO) {
        // 校验用户名是否已存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, registerDTO.getUsername());
        if (this.count(queryWrapper) > 0) {
            throw new BusinessException("用户名已存在");
        }

        // 校验邮箱是否已存在
        queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, registerDTO.getEmail());
        if (this.count(queryWrapper) > 0) {
            throw new BusinessException("邮箱已被注册");
        }

        // 校验两次密码是否一致
        if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
            throw new BusinessException("两次密码不一致");
        }

        // 创建用户
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(DigestUtil.md5Hex(registerDTO.getPassword())); // 密码加密
        user.setEmail(registerDTO.getEmail());
        user.setStorageQuota(DEFAULT_STORAGE_QUOTA);
        user.setStorageUsed(0L);
        this.save(user);

        // 返回用户信息
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        return userDTO;
    }

    @Override
    public UserDTO login(LoginDTO loginDTO) {
        // 查询用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, loginDTO.getUsername());
        User user = this.getOne(queryWrapper);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 校验密码
        if (!user.getPassword().equals(DigestUtil.md5Hex(loginDTO.getPassword()))) {
            throw new BusinessException("密码错误");
        }

        // 返回用户信息
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        return userDTO;
    }

    @Override
    public UserDTO getUserInfo(Integer userId) {
        User user = this.getById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        return userDTO;
    }

    @Override
    public StorageStatsDTO getStorageStats(Integer userId) {
        // 获取用户信息
        User user = this.getById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 构建存储统计信息
        StorageStatsDTO storageStatsDTO = new StorageStatsDTO();
        storageStatsDTO.setUsed(user.getStorageUsed());
        storageStatsDTO.setTotal(user.getStorageQuota());
        
        // 统计各类型文件数量
        storageStatsDTO.setDocuments(fileMapper.countByUserIdAndType(userId, "document"));
        storageStatsDTO.setImages(fileMapper.countByUserIdAndType(userId, "image"));
        storageStatsDTO.setVideos(fileMapper.countByUserIdAndType(userId, "video"));
        storageStatsDTO.setAudio(fileMapper.countByUserIdAndType(userId, "audio"));
        storageStatsDTO.setArchives(fileMapper.countByUserIdAndType(userId, "archive"));
        storageStatsDTO.setCode(fileMapper.countByUserIdAndType(userId, "code"));

        return storageStatsDTO;
    }

    @Override
    public boolean updateStorageUsed(Integer userId, Long size) {
        return baseMapper.updateStorageUsed(userId, size) > 0;
    }
} 